FTPで受信したファイルをイベントドリブンで処理させてみる
ウィスキー、シガー、パイプをこよなく愛する大栗です。 AWSでファイルのアップロード等は通常S3を使用していると思いますが、深遠な理由によりEC2上でFTPサーバを使用する場合が有ると思います。S3と異なりEC2はファイルが消える可能性が残っているので、ファイルの受信後にすぐ処理を行いと思います。ここではlsyncdを使用して対応してみました。
lsyncd
lsyncdはrsyncdと連動してリモートサーバへファイルのミラーリングを行うソフトウェアです。 lsyncdでは監視しているファイルのイベント処理をフックして外部の処理を行えますでの、それを利用します。
各種設定
環境
以下の環境で試しています。
OS :Cent OS 6.5 FTP :vsftpd 2.2.2 lsyncd:lsyncd 2.1.4
設定
FTP
diff vsftpd.conf.org vsftpd.conf
12c12 < anonymous_enable=YES --- > anonymous_enable=NO 81,82c81,82 < #ascii_upload_enable=YES < #ascii_download_enable=YES --- > ascii_upload_enable=YES > ascii_download_enable=YES 97c97 < #chroot_list_enable=YES --- > chroot_list_enable=YES 99c99 < #chroot_list_file=/etc/vsftpd/chroot_list --- > chroot_list_file=/etc/vsftpd/chroot_list 105c105 < #ls_recurse_enable=YES --- > ls_recurse_enable=YES 119a120,128 > > pasv_promiscuous=YES > > pasv_min_port=50000 > pasv_max_port=50030 > >
chroot_list
ftpuser
ここでftpuserというOSユーザも作成しています。
lsyncd
lsyncdの設定は"/usr/share/doc/lsyncd-2.1.4/examples/lecho.lua"を元に作成しました。
/etc/lsyncd.conf
----- -- User configuration file for lsyncd. -- -- This example uses local bash commands to keep two local -- directory trees in sync. -- ----- -- for testing purposes. just echos what is happening. -- settings = { logfile = "/var/log/lsyncd.log", statusFile = "/tmp/lsyncd.stat", nodeamon = false, } echo = { maxProcesses = 1, onStartup = "echo telling $(date --rfc-3339=seconds) about ^source | tee -a /tmp/lsyncd_status.txt", onCreate = "echo create $(date --rfc-3339=seconds) ^sourcePath | tee -a /tmp/lsyncd_status.txt", onDelete = "echo delete $(date --rfc-3339=seconds) ^sourcePath | tee -a /tmp/lsyncd_status.txt", onModify = "echo modify $(date --rfc-3339=seconds) ^sourcePath | tee -a /tmp/lsyncd_status.txt", onMove = "echo move $(date --rfc-3339=seconds) ^o.sourcePath -> ^d.sourcePath | tee -a /tmp/lsyncd_status.txt", } sync{echo, source="/home/ftpuser", target="/tmp/dst/"}
このように、onCreateやonDelete、onModifyで外部コマンドを呼び出して、対象のファイルのパスを "/tmp/lsyncd_status.txt" へ保存しています。
動作確認
ftp経由でファイルをアップロードします。
ファイルのアップロード
ftp> put text1.txt
出力ファイル(/tmp/lsyncd_status.txt)
create 2014-11-20 06:02:28+00:00 /home/ftpuser//text1.txt modify 2014-11-20 06:02:28+00:00 /home/ftpuser//text1.txt
Vvsftpdではファイルアップロード時に、一度保存した後にファイルの変更を行っているようです。
ファイルの削除
ftp経由でファイルを削除します。
ftp> del text1.txt
出力ファイル(/tmp/lsyncd_status.txt)
delete 2014-11-20 06:02:32+00:00 /home/ftpuser//text1.txt
ディレクトリの作成
ftp経由でディレクトリを作成します。
ftp> mkdir abd_dir
出力ファイル(/tmp/lsyncd_status.txt)
create 2014-11-20 06:00:45+00:00 /home/ftpuser//abc_dir/
ディレクトリの削除
ftp経由でディレクトリを削除します。
ftp> rmdir abd_dir
出力ファイル(/tmp/lsyncd_status.txt)
delete 2014-11-20 06:00:56+00:00 /home/ftpuser//abc_dir/
2014/11/20 18:25 追記
アップロードされたファイルをS3へ保存する例を書いてみました。"s3://lsyncd-to-s3-20141120"というS3バケットへ保存します。ここではmaxProcessesを10にして並列度を10にします。
/etc/lsyncd.conf
----- -- User configuration file for lsyncd. -- -- This example uses local bash commands to keep two local -- directory trees in sync. -- ----- -- for testing purposes. just echos what is happening. -- settings = { logfile = "/var/log/lsyncd.log", statusFile = "/tmp/lsyncd.stat", nodeamon = false, } echo = { maxProcesses = 10, onStartup = "echo telling $(date --rfc-3339=seconds) about ^source | tee -a /tmp/lsyncd_status.txt", onCreate = "aws s3 cp ^sourcePathname ^targetPathname | tee -a /tmp/lsyncd_status.txt", onDelete = "aws s3 rm ^targetPathname | tee -a /tmp/lsyncd_status.txt", onModify = "aws s3 cp ^sourcePathname ^targetPathname | tee -a /tmp/lsyncd_onModify.txt", onMove = "echo move $(date --rfc-3339=seconds) ^o.sourcePath -> ^d.sourcePath | tee -a /tmp/lsyncd_status.txt", } sync{echo, source="/home/ftpuser", target="s3://lsyncd-to-s3-20141120"}
この状態で1001.dat〜1010.datまでの10個のファイルを保存すると、以下の様に10プロセスが平行してアップロードできる事が分かります。
top - 09:06:34 up 17 min, 3 users, load average: 0.80, 0.26, 0.26 Tasks: 187 total, 1 running, 186 sleeping, 0 stopped, 0 zombie Cpu(s): 27.9%us, 6.2%sy, 0.0%ni, 64.2%id, 0.0%wa, 0.8%hi, 1.0%si, 0.0%st Mem: 15297700k total, 1663452k used, 13634248k free, 8520k buffers Swap: 0k total, 0k used, 0k free, 1072620k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2183 root 20 0 1122m 37m 4676 S 31.3 0.3 0:00.94 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1008.dat s3://lsyncd-to-s3-20141120/da 2168 root 20 0 1122m 39m 4676 S 30.3 0.3 0:00.91 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1003.dat s3://lsyncd-to-s3-20141120/da 2173 root 20 0 1122m 37m 4676 S 29.3 0.3 0:00.88 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1005.dat s3://lsyncd-to-s3-20141120/da 2171 root 20 0 1122m 39m 4672 S 28.9 0.3 0:00.87 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1007.dat s3://lsyncd-to-s3-20141120/da 2175 root 20 0 1122m 37m 4672 S 28.9 0.3 0:00.87 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1001.dat s3://lsyncd-to-s3-20141120/da 2181 root 20 0 1122m 39m 4676 S 28.9 0.3 0:00.87 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1009.dat s3://lsyncd-to-s3-20141120/da 2185 root 20 0 1122m 39m 4672 S 28.9 0.3 0:00.87 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1010.dat s3://lsyncd-to-s3-20141120/da 2167 root 20 0 1122m 39m 4672 S 28.6 0.3 0:00.86 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1004.dat s3://lsyncd-to-s3-20141120/da 2179 root 20 0 1122m 39m 4676 S 28.3 0.3 0:00.85 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1006.dat s3://lsyncd-to-s3-20141120/da 2166 root 20 0 1122m 39m 4676 S 27.6 0.3 0:00.83 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1002.dat s3://lsyncd-to-s3-20141120/da 1691 root 20 0 15028 1368 992 R 0.3 0.0 0:00.93 top
さいごに
lsyncdをファイルレプリケーションツールではなく、ファイルイベント検知フレームワークとして使用してみました。今回はechoを行っただけでしたが、同様に外部コマンドを呼ぶ事でftp受信後の自動バックアップ等も実装可能だと思いますので、皆さんで工夫してみて下さい。